<?php

namespace App\Http\Controllers\Stock;

use App\Http\Controllers\BaseController;
use App\Http\Controllers\Chanjet\TplusCommonController;
use App\Http\Validate\Purchase\StockAllotOrder as PurchaseStockAllotOrder;
use App\Models\Stock\Stock;
use App\Models\Stock\StockAllotOrder;
use App\Models\Stock\StockAllotOrderSub;
use App\Models\Warehouse\WarehouseList;
use App\Services\Chanjet\ChanjetRequest;
use App\Services\Common\SnCode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Services\Stock\Stock as StockStock;
use App\Models\Stock\StockSub;

class StockAllotOrderController extends BaseController
{

    public function dopostadd(Request $request){
        $sub_order = is_array($request->suborder) ? $request->suborder : (is_array(json_decode($request->suborder, true)) ? json_decode($request->suborder, true) : []);
        $cpid = $this->mangerinfo['cpid'];
        $manger_id = $this->mangerinfo['id'];
        $order_sn_code=SnCode::getSnCode('SAO_');
        $warehouse_id_out=intval($request->warehouse_id_out);
        $warehouse_id_in=intval($request->warehouse_id_in);
        if($warehouse_id_in<=0){
            return response()->json(['code' => '001', 'msg' => '请选择入库仓库']);
        }
        if($warehouse_id_out<=0){
            return response()->json(['code' => '001', 'msg' => '请选择出库仓库']);
        }
        if($warehouse_id_in==$warehouse_id_out){
            return response()->json(['code' => '001', 'msg' => '入库仓库与出库仓库不能相同']);

        }

        $warehouse_id_out_info=WarehouseList::where([['id',$warehouse_id_out],['cpid',$cpid],['status',1]])->first();
        if(!$warehouse_id_out_info){
            return response()->json(['code' => '001', 'msg' => '出库仓库不存在或已冻结']);

        }
        $tplus_warehouse_no_out = $warehouse_id_out_info['warehouse_no'];
        $warehouse_id_in_info=WarehouseList::where([['id',$warehouse_id_in],['cpid',$cpid],['status',1]])->first();
        if(!$warehouse_id_in_info){
            return response()->json(['code' => '001', 'msg' => '入库仓库不存在或已冻结']);
        }

        $maindata=[
            'cpid'=>$cpid,
            'manger_id' => $this->mangerinfo['id'],
            'order_sn_code' => $order_sn_code,
            'warehouse_id_out' => $warehouse_id_out,
            'warehouse_name_out' => $warehouse_id_out_info['warehouse_name'],
            'warehouse_id_in' => $warehouse_id_in,
            'warehouse_name_in' => $warehouse_id_in_info['warehouse_name'],
            'remark' => strval($request->remark),
            'create_at' => time(),
            'update_at' => time(),
        ];


        $money_out = 0;

        $sub_order_arr = [];
        if (count($sub_order) > 0) {

            $ValidateSub = new PurchaseStockAllotOrder();
            foreach ($sub_order as $s_order) {
                $total_money = $s_order['total_money'] ?? 0;
                $money_out += $total_money ?? 0;
                $s_order = is_array($s_order) ? $s_order : json_decode($s_order, true);
                if (!$ValidateSub->check($s_order)) { //初筛过滤
                    return response()->json(['code' => '001', 'msg' => $ValidateSub->getError()]);
                }

                $stockinfo = Stock::where([['id', $s_order['stock_id']],['cpid',$cpid],['warehouse_id',$warehouse_id_out]])->first();
                if (!$stockinfo) {
                    return response()->json(['code' => '001', 'msg' => '无效库存信息']);
                }
                $stockinfo = $stockinfo->toArray();

                if ($stockinfo['archive_type'] == 4){
                    return response()->json(['code' => '001', 'msg' => '该库存为虚拟库存，不能进行调拨操作']);
                }


                if ($s_order['count']>$stockinfo['can_use_pieces']) {
                    return response()->json(['code' => '001', 'msg' => '库存可用数量不足']);
                }

                if (in_array($stockinfo['archive_type'], [2, 3])) {
                    if (isset($s_order['total_weight']) && doubleval($s_order['total_weight']) > 0) {
                        $s_order['total_weight'] = doubleval($s_order['total_weight']);
                        if ($s_order['total_weight'] > $stockinfo['can_use_weight']) {
                            return response()->json(['code' => '001', 'msg' => '库存可用重量不足']);
                        }
                    } else {
                        return response()->json(['code' => '001', 'msg' => '请输入总重']);
                    }
                    $s_order['count'] = intval($s_order['count']);
                }
//                else{
//                    $s_order['weight'] = mathtoweightbyarchivetype($stockinfo['archive_spec'], $stockinfo['archive_type']);
//
//                    $s_order['total_weight'] = mathfuncweight('mul', $s_order['weight'], $s_order['count'], 1);
//
//                    if ($s_order['total_weight'] > $stockinfo['can_use_weight']) {
//                        return response()->json(['code' => '001', 'msg' => '库存可用重量不足']);
//                    }
//                }

                $sub_sub_order = isset($s_order['sub_sub_order']) ? (is_array($s_order['sub_sub_order']) ? $s_order['sub_sub_order'] : (is_array(json_decode($s_order['sub_sub_order'], true)) ? json_decode($s_order['sub_sub_order'], true) : [])) : [];

                if ($stockinfo['archive_type'] == 1) {

                    $length_count = 0;
                    $total_weight = 0;
                    foreach ($sub_sub_order as &$subsubval) {
                        if(!(isset($subsubval['stock_sub_id']) && $subsubval['stock_sub_id']>0)){
                            return response()->json(['code' => '001', 'msg' => '子库存信息有误']);
                        }

                        if (
                            $subsubval['length'] <= 0 || $subsubval['count'] <= 0 || $subsubval['stock_num'] == ''
                            || $subsubval['origin'] == ''  || $subsubval['layer_num'] == ''
                        ) {
                            return response()->json(['code' => '001', 'msg' => '理计码单信息有误']);
                        }
                        $length = $subsubval['length'];
                        $count = $subsubval['count'];
                        $length_count = bcadd($length_count, $count);
                        $weight = mathtoweightbyarchivetype($stockinfo['archive_spec'], $stockinfo['archive_type'], $length); //kg
                        $total_weight = mathfuncweight('add', $total_weight, mathfuncweight('mul', mathfuncweight('mul', $weight, 10), $count)); //kg*10
                        $subsubval['weight'] = mathfuncweight('mul', $weight, 10);
                        $subsubval['total_weight'] = mathfuncweight('mul', mathfuncweight('mul', $weight, 10), $count);
                    }
                    unset($subsubval);

                    if ($length_count != $s_order['count']) {
                        return response()->json(['code' => '001', 'msg' => '理计码单长度件数不匹配']);
                    }
                    $s_order['total_weight'] = $total_weight; //kg*10
                    $s_order['weight'] = mathfuncweight('div', $total_weight, $length_count); //kg*10

                    if ($s_order['total_weight'] > $stockinfo['can_use_weight']) {
                        return response()->json(['code' => '001', 'msg' => '库存可用重量不足']);
                    }

                }


                if ($stockinfo['archive_type'] == 3) {
                    $stockinfo['weight'] = mathtoweightbyarchivetype($stockinfo['archive_spec'], $stockinfo['archive_type']);

                    $length_count = 0;
                    foreach ($sub_sub_order as &$subsubval) {
                        if(!(isset($subsubval['stock_sub_id']) && $subsubval['stock_sub_id']>0)){
                            return response()->json(['code' => '001', 'msg' => '子库存信息有误']);
                        }

                        if (
                            $subsubval['count'] <= 0 || $subsubval['stock_num'] == ''
                            || $subsubval['origin'] == ''  || $subsubval['layer_num'] == ''
                        ) {
                            return response()->json(['code' => '001', 'msg' => '定尺码单信息有误']);
                        }



                        $count = $subsubval['count'];
                        $length_count = bcadd($length_count, $count);
                        $subsubval['weight'] = mathfuncweight('mul', $stockinfo['weight'], 10); //kg*10
                        $subsubval['total_weight'] = intval(mathfuncweight('mul', $subsubval['weight'], $subsubval['count']));
                   }
                    unset($subsubval);
                    if ($length_count != $s_order['count']) {
                        return response()->json(['code' => '001', 'msg' => '定尺码单入库件数不匹配']);
                    }

                    $s_order['weight'] = mathfuncweight('mul', $stockinfo['weight'], 10); //kg*10
                    $s_order['total_weight'] = intval(mathfuncweight('mul', $s_order['weight'], $s_order['count'])); //kg*10
                }




                if ($stockinfo['archive_type'] == 2) { //过磅


                    //计算重量
                    $length_count = 0;
                    $total_weight = 0;
                    foreach ($sub_sub_order as &$subsubval) {
                        if(!(isset($subsubval['stock_sub_id']) && $subsubval['stock_sub_id']>0)){
                            return response()->json(['code' => '001', 'msg' => '子库存信息有误']);
                        }

                        if (
                            $subsubval['count'] <= 0 || $subsubval['stock_num'] == ''
                            || $subsubval['origin'] == ''  || $subsubval['layer_num'] == '' || $subsubval['total_weight'] <= 0
                        ) {
                            return response()->json(['code' => '001', 'msg' => '过磅码单信息有误']);
                        }
                        $subsubval['length'] = isset($subsubval['length']) ? $subsubval['length'] : 0;

                        $count = $subsubval['count'];
                        $length_count = bcadd($length_count, $count);

                        $subsubval['total_weight'] = mathfuncweight('mul', $subsubval['total_weight'], 10); //kg*10
                        $subsubval['weight'] = intval(mathfuncweight('div', $subsubval['total_weight'], $subsubval['count']));
                    }
                    unset($subsubval);



                    if(count($sub_sub_order)>0){
                        if($length_count!= $s_order['count']){
                            return response()->json(['code' => '001', 'msg' => '过磅码单入库件数不匹配']);
                        }
                    }


                    $s_order['total_weight'] = mathfuncweight('mul', $s_order['total_weight'], 10); //kg*10

                    $s_order['weight'] = mathfuncweight('div', $s_order['total_weight'], $s_order['count']); //kg*10
                }


                $item=[
                    'cpid' => $cpid,
                    'stock_id' => $stockinfo['id'],
                    'steel_archive_id'=>$stockinfo['steel_archive_id'],
                    'count' => $s_order['count'],
                    'weight' => $s_order['weight'],
                    'total_weight' => $s_order['total_weight'],
                    'total_money' => $s_order['total_money'],
                    'price' => $s_order['supply_price'],
                    'warehouse_id' => $warehouse_id_out,
                    'warehouse_name' => $stockinfo['warehouse_name'],
                    'sub_sub_order'=>$sub_sub_order,
                    'archive_no' => $stockinfo['archive_no'],
                    'archive_name' => $stockinfo['archive_name'],
                    'archive_spec' => $stockinfo['archive_spec'],
                    'archive_material' => $stockinfo['archive_material'],
                    'steel_factory_name' => $stockinfo['steel_factory_name'],
                    'breed_name' => $stockinfo['breed_name'],
                    'archive_type' => $stockinfo['archive_type'],
                    'remark' => isset($s_order['remark']) ? $s_order['remark'] : '',
                ];
                $sub_order_arr[]=$item;
            }



        }else{
            return response()->json(['code' => '001', 'msg' => '请选择要出库的子订单']);
        }

        $maindata['money_out'] = $money_out;
        $maindata['money_in'] = $money_out;
        /***
         *  更新数据结构
         *
        */
        if($sub_order_arr){
            foreach ($sub_order_arr as $key => $val) {
                $sub_order_arr[$key]["sub_sub"] = $val['sub_sub_order'];
                unset($sub_order_arr[$key]['sub_sub_order']);
            }
        }


        $TransDetails = []; //调拨明细
        DB::beginTransaction();
        try {

            $order_id=StockAllotOrder::create($maindata)->id;

            foreach ($sub_order_arr as &$subval) {
                $subval['order_id']=$order_id;
                $warehouse_id_out_info = Stock::where([
                    ['steel_archive_id', $subval['steel_archive_id']],
                    ['cpid', $cpid],
                    ['warehouse_id', $warehouse_id_in]])
                    ->select(['id', 'warehouse_name','warehouse_id']) // 明确指定需要的字段
                    ->first();

                $stock_id=$warehouse_id_out_info->id;

                $ins_data=[];
                foreach ($subval['sub_sub'] as $subsubval) {
                    $item = [
                        'cpid' => $cpid,
                        'stock_id' => $stock_id,
                        'warehouse_name' => $warehouse_id_out_info->warehouse_name, //转入仓库名称
                        'length' => $subsubval['length'],
                        'weight' => $subsubval['weight'],
                        'total_weight' => $subsubval['total_weight'],
                        'can_use_weight' => $subsubval['total_weight'],
                        'can_use_pieces' => $subsubval['count'],
                        'current_pieces' => $subsubval['count'],
                        'current_weight' => $subsubval['total_weight'],
                        'warehousing_at' => time(),
                        'stock_num' => $subsubval['stock_num'],
                        'origin' => $subsubval['origin'],
                        'layer_num' => $subsubval['layer_num'],
                        'price' => $subsubval['price'],
                        'archive_no' => $subval['archive_no'],
                        'archive_name' => $subval['archive_name'],
                        'archive_spec' => $subval['archive_spec'],
                        'archive_material' => $subval['archive_material'],
                        'steel_factory_name' => $subval['steel_factory_name'],
                        'breed_name' => $subval['breed_name'],
                        'archive_type' => $subval['archive_type'],
                        'carship_no' => $subsubval['carship_no'],  //保留原来的车船号
                        'contract_no' => $subsubval['contract_no'],  //保留原来的合同号
                        'wo_order_sn_code' => $subsubval['wo_order_sn_code'],  //保留原来的入库单据号
                        'total_money' => $subsubval['total_money'],  //保留原来的总金额

                    ];
                    $ins_data[] = $item;
                    /****
                     *  出库子库存钢材，减子库存，只减 件数 重量
                     *
                     *
                    */
                    StockSub::where(['id'=>$subsubval['stock_sub_id']])->update(
                        [

                            'current_pieces' => DB::raw('current_pieces - ' . $subsubval['count']),
                            'current_weight' => DB::raw('current_weight - ' . $subsubval['total_weight']),
                            'can_use_weight' => DB::raw('can_use_weight - ' . $subsubval['total_weight']),
                            'can_use_pieces' => DB::raw('can_use_pieces - ' . $subsubval['count']),
                            'total_weight' => DB::raw('total_weight - ' . $subsubval['total_weight'])
//                            'can_use_pieces' => DB::raw('can_use_pieces - ' . $subsubval['count'])
                        ]
                    );


                }
                $TransDetails[] = [
                    "Inventory" => ["Code" => $subval['archive_no']],
                    "Quantity" => mathfunc('div',strval($subval["total_weight"]),10000,4),
                    "Unit" => ["Name" => "吨"],
                    "ChangeRate" => "1",//单位换算率
                    "Unit2" => ["Name" => "件"],
                    "Quantity2" => strval($subval["count"]),
                    'OutAmount' => mathfunc('div',$subval['total_money']??0,100,2),//调出金额
                    'InAmount' => mathfunc('div',$subval['total_money']??0,100,2),//调出金额
                    "DynamicPropertyKeys" => ["pubuserdefnvc1", "pubuserdefnvc2", "pubuserdefnvc3"],
                    "DynamicPropertyValues" => [$subval['steel_factory_name'], $subval['breed_name'], $subval['archive_material']],
                ];

                $subval['sub_sub_order']=json_encode($subval['sub_sub']);
                StockStock::doStockIn($cpid, $subval['stock_id'], -$subval['count'], -$subval['total_weight'], 3);
                StockStock::doStockIn($cpid, $stock_id, $subval['count'], $subval['total_weight'], 3);

                /****
                 *  当前库存钢材，加子库存，只减 件数 重量
                 *
                 *
                 */
                StockSub::insert($ins_data);
                unset($subval['sub_sub']);
            }
            StockAllotOrderSub::insert($sub_order_arr);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            Log::info($e->getMessage());
            return response()->json(['code' => '001', 'msg' => '调拨单入库失败' . $e->getMessage()]);
        }

        /***
         *  T+调拨单同步 2025.03.04
         *
        */
        $Chanjet_param = [
            "dto"=>
                [
                    "ExternalCode" => $order_sn_code,
                    "IsModifiedCode" => "true",
                    "Code" => $order_sn_code,
                    "VoucherType" => ["Code" => "ST1031"],
                    "VoucherDate" => date("Y-m-d"),
                    "BusiType" => ["Code" => "26"], //26：同价调拨 27：异价调拨
                    "OutWarehouse" => ["Code" => $tplus_warehouse_no_out],//调出仓库
                    "InWarehouse" => ["Code" => $warehouse_id_in_info['warehouse_no']],//调入仓库
                    "Clerk" => ["Code" => $this->mangerinfo['code_no']],
                    "TransDetails" => $TransDetails
                ]
        ];
        $requestData = [
            "api" => "TransVoucherOpenApiCreate",
            "param" => $Chanjet_param,
            "mangerinfo" => $this->mangerinfo
        ];
        \App\Jobs\TransferOrder::dispatch($requestData);


        return response()->json(['code' => '000', 'msg' => '调拨单入库成功']);


    }
    public function getlist(Request $request)
    {
        $list=StockAllotOrder::getList($request, $this->mangerinfo['cpid']);
        //增加业务类型 t+写死同价调拨，2025.04.06
        if(isset($list["list"])){
            foreach ($list["list"] as &$item){
                $item["business_type"] = "同价调拨";
            }
        }
        return response()->json(['code' => '000', 'msg' => '操作成功', 'data' => $list]);
    }


    public function getinfo(Request $request)
    {
        $order_id = $request->order_id ?? 0;
        $cpid = $this->mangerinfo['cpid'];
        $info = StockAllotOrder::where(['id' => $order_id,  'cpid' => $cpid, 'is_del' => 1])->with(['suborder'])->first();
        if (!$info) {
            return response()->json(['code' => '001', 'msg' => '无效参数']);
        }

        return response()->json(['code' => '000', 'msg' => '操作成功', 'data' => ['info' => $info]]);
    }

    public function dodel(Request $request)
    {
        $order_id = $request->order_id ?? 0;
        $cpid = $this->mangerinfo['cpid'];
        $info = StockAllotOrder::where(['id' => $order_id,  'cpid' => $cpid, 'is_del' => 1])->with(['suborder'])->first();
        if (!$info) {
            return response()->json(['code' => '001', 'msg' => '无效参数']);
        }

        StockAllotOrder::where(['id' => $order_id,  'cpid' => $cpid, 'is_del' => 1])->update(['is_del'=>2,'del_at'=>time()]);
        StockAllotOrderSub::where(['order_id' => $order_id,  'cpid' => $cpid, 'is_del' => 1])->update(['is_del'=>2,'del_at'=>time()]);

        /**
         *  调拨单删除 2025.03.04
        */
        if(TplusCommonController::isAllowRequestTplus($this->mangerinfo)){
            $Chanjet_param = [
                "param" => [
                    "voucherCode" => $info["order_sn_code"],//单据编号
                ]
            ];
            ChanjetRequest::getInstance()->TransVoucherOpenApiDelete($Chanjet_param,[$this->mangerinfo["org_id"]]);
        }
        return response()->json(['code' => '000', 'msg' => '操作成功']);
    }
}
